#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "securec.h"
#include "discovery_service.h"
#include "softbus_bus_center.h"
#include "session.h"

#define PACKAGE_NAME "softbus_sample"
#define LOCAL_SESSION_NAME "session_test"
#define TARGET_SESSION_NAME "session_test"
#define DEFAULT_CAPABILITY "osdCapability"
#define DEFAULT_SESSION_GROUP "group_test"
#define DEFAULT_PUBLISH_ID 123

static int g_sessionId;


static int SessionOpened(int sessionId, int result)
{
        printf("<SessionOpened>CB: session %d open fail:%d\n", sessionId, result);
        if (result == 0) {
                g_sessionId = sessionId;
        }

        return result;
}

static void SessionClosed(int sessionId)
{
        printf("<SessionClosed>CB: session %d closed\n", sessionId);
}

static void ByteRecived(int sessionId, const void *data, unsigned int dataLen)
{
        printf("<ByteRecived>CB: session %d received %u bytes data=%s\n", sessionId, dataLen, (const char *)data);
}

static void MessageReceived(int sessionId, const void *data, unsigned int dataLen)
{
        printf("<MessageReceived>CB: session %d received %u bytes message=%s\n", sessionId, dataLen, (const char *)data);
}

static void StreamReceived(int sessionId, const StreamData *data, const StreamData *ext,
        const StreamFrameInfo *param)
{
        printf("<StreamReceived>CB: session %d received ");
        printf("streaminfo:%s\n", data->buf);
}

static int CreateSessionServerInterface(void)
{
        const ISessionListener sessionCB = {
                .OnSessionOpened = SessionOpened,
                .OnSessionClosed = SessionClosed,
                .OnBytesReceived = ByteRecived,
                .OnMessageReceived = MessageReceived,
                .OnStreamReceived = StreamReceived,
        };

        return CreateSessionServer(PACKAGE_NAME, LOCAL_SESSION_NAME, &sessionCB);
}

static void RemoveSessionServerInterface(void)
{
        int ret = RemoveSessionServer(PACKAGE_NAME, LOCAL_SESSION_NAME);
        if (ret) {
                printf("RemoveSessionServer fail:%d\n", ret);
        }
}



static int OpenSessionInterface_file(const char *peerNetworkId)
{
        SessionAttribute attr = {
                .dataType = TYPE_FILE,
                .linkTypeNum = 1,
                .linkType[0] = LINK_TYPE_WIFI_WLAN_2G,
                .attr = {RAW_STREAM},
        };

        return OpenSession(LOCAL_SESSION_NAME, TARGET_SESSION_NAME, peerNetworkId, DEFAULT_SESSION_GROUP, &attr);
}




static void CloseSessionInterface(int sessionId)
{
        CloseSession(sessionId);
}

static int GetAllNodeDeviceInfoInterface(NodeBasicInfo **dev)
{
        int ret, num;

        ret = GetAllNodeDeviceInfo(PACKAGE_NAME, dev, &num);
        if (ret) {
                printf("GetAllNodeDeviceInfo fail:%d\n", ret);
                return -1;
        }

        printf("<GetAllNodeDeviceInfo>return %d Node\n", num);
        for (int i = 0; i < num; i++) {
                printf("<num %d>deviceName=%s\n", i + 1, dev[i]->deviceName);
                printf("\tnetworkId=%s\n", dev[i]->networkId);
                printf("\tType=%d\n", dev[i]->deviceTypeId);
        }

        return num;
}

static void FreeNodeInfoInterface(NodeBasicInfo *dev)
{
        FreeNodeInfo(dev);
}



static int ReceiveFileStarted(int sessionId, const char *files, int fileCnt){
        printf("start receive %d files!\n", fileCnt);
        return fileCnt;
}

static int ReceiveFileProcess(int sessionId, const char *firstFile, uint64_t bytesUpload, uint64_t bytesTotal){
        printf("on receivefile process %d %d \n", bytesUpload, bytesTotal);
        return  sessionId;
}

void ReceiveFileFinished(int sessionId, const char *files, int fileCnt){
        printf("finished receive %d files!\n", fileCnt);
}

void FileTransError(int sessionId){
        printf("file trans error %d \n", sessionId);
}

static void SetFileReceiveListenerInterface(){
        const IFileReceiveListener filereceiveListener={
                .OnFileTransError=FileTransError,
                .OnReceiveFileFinished=ReceiveFileFinished,
                .OnReceiveFileProcess=ReceiveFileProcess,
                .OnReceiveFileStarted=ReceiveFileStarted,
        };
        int ret = SetFileReceiveListener(PACKAGE_NAME,TARGET_SESSION_NAME,&filereceiveListener,NULL);
        if(!ret){
                printf("set file listener failed errornode:%d \n", ret);
        }
}

static int SendFileProcess(int sessionId, uint64_t bytesUpload, uint64_t bytesTotal){
        printf("on SendFileProcess process %d %d \n", bytesUpload, bytesTotal);
        return  sessionId;
}

static int SendFileFinished(int sessionId, const char *firstFile){
        printf("SendFile  Finished!\n");
}


static void SetFileSendListenerInterface(){
        const IFileSendListener filesendlistener = {
                .OnFileTransError = FileTransError,
                .OnSendFileFinished = SendFileFinished,
                .OnSendFileProcess = SendFileProcess,
        };
        int ret = SetFileSendListener(PACKAGE_NAME,TARGET_SESSION_NAME,&filesendlistener);
        if(!ret){
                printf("Set FileSend Listener failed errorno: %d\n",ret);
        }
}

static void commnunicate_file(void)
{
        NodeBasicInfo *dev = NULL;
        int dev_num, sessionId, input, ret;
        int timeout = 5;

        dev_num = GetAllNodeDeviceInfoInterface(&dev);
        if (dev_num <= 0) {
                return;
        }

        printf("\nInput Node num to commnunication:");
        scanf_s("%d", &input);
        if (input <= 0 || input > dev_num) {
                printf("error input num\n");
                goto err_input;
        }

        g_sessionId = -1;
        sessionId = OpenSessionInterface_file(dev[input - 1].networkId);
        printf("sessionId: %d\n", sessionId);
        if (sessionId < 0)
        {
                printf("OpenSessionInterface fail, ret=%d\n", sessionId);
                goto err_OpenSessionInterface;
        }

        printf("openopenopen  sessionID: %d\n", sessionId);

        const char *sfileList[] = {
                "/home/zhuqingsong/0908.png",
                "/home/zhuqingsong/ifconfig_eth0.png",
        };

        SetFileReceiveListenerInterface();
        SetFileSendListenerInterface();
        while (timeout)
        {
                if (g_sessionId == sessionId) {
                        ret = SendFile(sessionId, sfileList, NULL, 2);
                        if (ret)
                        {
                                printf("SendMessage fail:%d\n", ret);
                        }
                        break;
                }
                timeout--;
                sleep(1);
        }

        CloseSessionInterface(sessionId);
err_OpenSessionInterface:
err_input:
        FreeNodeInfoInterface(dev);
}


int main(int argc, char **argv)
{
        bool loop = true;
        int ret;

        ret = CreateSessionServerInterface();
        if (ret) {
                printf("CreateSessionServer fail, ret=%d\n", ret);
                return ret;
        }


        NodeBasicInfo *dev = NULL;
        int dev_num;
        dev_num = GetAllNodeDeviceInfoInterface(&dev);

        

        while (loop) {
                printf("\nInput c commnuication, Input s to stop:");
                char op = getchar();
                switch(op) {
                case 'c':
                        commnunicate_file();
                        continue;
                case 's':
                        loop = false;
                        break;
                case '\n':
                        break;
                default:
                        continue;
                }
        }

        RemoveSessionServerInterface();
        return 0;
}
